#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<vector>
#include<cerrno>
#include<string>
#include<cstring>
#include"test.hpp"
#define PROCESSMAX 3
Test t;
class proc
{

public:
    proc(int pip,pid_t pid)
    :pip(pip),
    pid(pid)
    {

    }
    int pip;
    pid_t pid;
};
void WaitCommand()
{

    while(true)
    {
        int command = 0;
        int n = read(0,&command,sizeof(command));
        if(n > 0)
        {
            printf("我是%d进程，我在执行%d任务\n",getpid(),command+1);
            t[command]();
        }
        else if (n == 0)
        {
            //对方关闭了管道
            return;
        }
        else
        {
            //错误
        }
    
    }
    
}


void CreatProc(std::vector<proc>& p)
{
    for(int i = 0;i < PROCESSMAX; i++)
    {
        int pip[2];
        int n = pipe(pip);
        if(n == -1)
        {
            //错误
            //int a = erron;
            //std::cout<<strerror(erron);
        }

        pid_t id = fork();
        if(id == -1)
        {
            //错误
        } 



        //子进程
        ///////////////
        if(id == 0)
        {
            
            //子进程要读，关闭pip[1]
            //close(pip[1]);
            for(proc& e:p)
            {
                //std::cout << e.pip<<" ";
                close(e.pip);
            }
            //std::cout << std::endl;
            close(pip[1]);
            dup2(pip[0],0);

            WaitCommand();

            close(pip[0]);
            exit(0);
        }
        ///////////////
        //构造管道表父进程要写，所以关闭pip[0]
        close(pip[0]);
        p.push_back(proc(pip[1],id));

    }
}


void menu()
{

    printf("**********************************\n");
    printf("* 0.quit 1.Test1 2.Test2 3.Test3 *\n");
    printf("**********************************\n");


}

void ControlProc(std::vector<proc>& p)
{
    int tmp = 0;//控制进程
    while(true)
    {
        menu();

        tmp%=PROCESSMAX;
        int command = 0;//控制命令
        scanf("%d",&command);
        if(command == 0)
        {
            return;
        }
        if(command > PROCESSMAX || command < 0)
        {
            std::cout << "please enter 0~"<< PROCESSMAX<<std::endl;
            continue;
        }

        printf("现在是%d进程执行%d任务\n",p[tmp].pid,command);
        command -= 1;
        int n = write(p[tmp++].pip,&command,sizeof(command));
        if(n  == -1)
        {
            //出错了；
        }
        sleep(1);
    }


}

void FreeProc(std::vector<proc>& p)
{

    for(proc& e:p)
    {
        
        int i = close(e.pip);

        if(i == -1)
        {
            //出错了
        }

        pid_t id = waitpid(e.pid,nullptr,0);
        std::cout << "我释放了:"<<id<<std::endl;

    }


}

int main()
{
    std::vector<proc> p;



    CreatProc(p);


    // for(auto& e:p)
    // {
    //     std::cout << e.pid<<' '<<e.pip<<std::endl;
    // }

    ControlProc(p);
    FreeProc(p);




    
    return 0;
}
